import { useRef } from 'react'

const has = Object.prototype.hasOwnProperty

export function dequal(foo: any, bar: any) {
	let ctor, len
	if (foo === bar) return true

	if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
		if (ctor === Date) return foo.getTime() === bar.getTime()
		if (ctor === RegExp) return foo.toString() === bar.toString()

		if (ctor === Array) {
			if ((len = foo.length) === bar.length) {
				while (len-- && dequal(foo[len], bar[len]));
			}
			return len === -1
		}

		if (!ctor || typeof foo === 'object') {
			len = 0
			for (ctor in foo) {
				if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false
				if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false
			}
			return Object.keys(bar).length === len
		}
	}
	// eslint-disable-next-line no-self-compare
	return foo !== foo && bar !== bar
}

export function useDeepCompare(value: any) {
	const ref = useRef()
	const signalRef = useRef(0)

	if (!dequal(value, ref.current)) {
		ref.current = value
		signalRef.current += 1
	}

	return [signalRef.current]
}
